/*
 * Licensed Materials - Property of tenxcloud.com
 * (C) Copyright 2018 TenxCloud. All Rights Reserved.
 * 2018-06-19  @author lizhen
 */

package middleware

import (
	"github.com/gin-gonic/gin"
	"github.com/golang/glog"
	"modules.tenxcloud.com/common/composite"
	"modules.tenxcloud.com/common/contract"
	"modules.tenxcloud.com/common/model/audit"
	"modules.tenxcloud.com/common/utility/errors"
)

const (
	AuditInfoKey = "audit-info"
)

func Audit(c *gin.Context) {
	var clusterID string
	var namespace string
	var username string
	var body string
	li, exist := c.Get(LoginUserKey)
	if exist {
		l := li.(contract.LoginInfo)
		username = l.GetUserName()
	}
	ns, exist := c.Get(NamespaceKey)
	if exist {
		n := ns.(contract.Namespace)
		namespace = n.Space()
	}
	ci, exist := c.Get(ClusterInfoKey)
	if exist {
		c := ci.(clusterInfo)
		clusterID = c.GetID()
	}
	rb, exist := c.Get(RequestBodyKey)
	if exist {
		r := rb.([]byte)
		body = string(r)
	}
	db, err := composite.Database.GetOrm()
	if err != nil {
		glog.Warningf("get db connection failed, %s", err)
		c.AbortWithStatusJSON(errors.InternalServerError(err))
		return
	}
	record := audit.NewModel(clusterID, namespace, c.Request.URL.String(), c.Request.Header.Get("X-Forwarded-For"), c.Request.Method, username, body)
	c.Set(AuditInfoKey, record)
	pool := composite.Pool
	pool.Enqueue(func() {
		if err := record.Insert(db); err != nil {
			glog.Errorf("insert audit info failed, %s", err)
		}
	})
	c.Next()
	pool.Enqueue(func() {
		record.SetHttpCode(c.Writer.Status())
		record.SetDuration()
		if err := record.Update(db); err != nil {
			glog.Errorf("update audit info failed, %s", err)
		}
	})
}
